﻿using IPC.DbMapper.IPCDBConnect;
using IPC.DbMapper;
using IPC.LogCommon.DelegateAndEvent;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Driver;
using IPC.LogCommon.log4net;
using MongoDB.Bson;

namespace IPC.MongoDB
{
    public class MongoOperate
    {
        private static MongoOperate _instance;
        private static readonly object _lock = new object();
        private static MongoClient _client;
        private static IMongoDatabase db;
        private bool _isConnect = false;
        public static MongoOperate Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock)
                    {
                        if(_instance == null)
                        {
                            _instance = new MongoOperate();
                        }
                    }
                }
                return _instance;
            }
        }

        public MongoOperate()
        {
            try
            {
                string connStr = $"mongodb://{GetConfigByKey("mongoIP", "127.0.0.1")}:{GetConfigByKey("mongoPort", "27017")}";
                _client = new MongoClient(connStr);
                db = _client.GetDatabase("IPC");
                _isConnect = true;
            }
            catch(Exception ex)
            {
                _isConnect = false;
                LogClass.Instance.Error($"实时库连接失败{ex.Message}");
            }
        }

        public void Insert(string name,string recordTime,double value)
        {
            IMongoCollection<BsonDocument> collection = db.GetCollection<BsonDocument>(name);
            var document = new BsonDocument { { "RecordTime", recordTime }, { "Value", value } };
            collection.InsertOne(document);
        }

        public List<BsonDocument> Select(string name,string beginTime,string endTime)
        {
            try
            {
                IMongoCollection<BsonDocument> collection = db.GetCollection<BsonDocument>(name);
                var filter = Builders<BsonDocument>.Filter.And(
                    Builders<BsonDocument>.Filter.Gte("RecordTime", beginTime),
                    Builders<BsonDocument>.Filter.Lte("RecordTime", endTime)
                    );
                var list = collection.Find(filter).ToList();
                return list;
            }
            catch (Exception ex) {
                LogClass.Instance.Error("Mongodb查询错误"+ex.Message);
                return new List<BsonDocument>();
            }
        }

        /// <summary>
        /// 查询最新一条数据
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<BsonDocument> Select(string? name)
        {
            try
            {
                IMongoCollection<BsonDocument> collection = db.GetCollection<BsonDocument>(name);
                var filter = Builders<BsonDocument>.Filter.Empty;
                var sort = Builders<BsonDocument>.Sort.Descending("RecordTime");
                var options = new FindOptions<BsonDocument> { Sort = sort };
                return collection.Find(filter).Sort(sort).Limit(1).ToList();
            }
            catch (Exception ex)
            {
                LogClass.Instance.Error("Mongodb查询错误" + ex.Message);
                return new List<BsonDocument>();
            }
        }

        #region 获取配置
        public string GetConfigByKey(string configKey, string defaultValue = "")
        {
            try
            {
                IPCDbContext iPCDbContext = new IPCDbContext();
                List<SystemConfig> systemConfigs = iPCDbContext.SystemConfigs.Where(o => o.ConfigKey == configKey).ToList();
                if (systemConfigs.Count > 0)
                {
                    iPCDbContext.Dispose();
                    return systemConfigs[0].ConfigValue;
                }
                return defaultValue;
            }
            catch (Exception ex)
            {
                DelegateAndEvent.Instance.AddAlarmInfo($"获取系统配置{configKey}失败 {ex.Message}");
                return defaultValue;
            }
        }
        #endregion
    }
}
